import dashscope
from dashscope.audio.tts_v2 import VoiceEnrollmentService, SpeechSynthesizer
import base64
from typing import Dict, Any, Tuple, Optional
import logging

# 配置日志记录器
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

class AliyunSpeechSynthesizer:
    """阿里云语音合成器类，用于管理语音合成相关操作"""
    
    def __init__(self, default_model: str = "cosyvoice-v1"):
        """
        初始化语音合成器
        
        参数:
        default_model: 默认使用的语音合成模型
        """
        self.default_model = default_model
    
    def synthesize_speech(self, api_key: str, voice_id: str, text: str, model: str = None) -> Tuple[bool, Dict[str, Any], bytes]:
        """
        使用阿里云DashScope进行语音合成
        
        参数:
        api_key: DashScope API密钥
        voice_id: 声音ID
        text: 待合成的文本
        model: 使用的模型，如果不指定则使用默认模型
        
        返回:
        Tuple[bool, Dict[str, Any], bytes]: 
        - 成功状态
        - 响应数据或错误信息
        - 音频数据（如果成功）
        """
        if model is None:
            model = self.default_model
            
        try:
            # 设置API密钥
            dashscope.api_key = api_key
            
            # 初始化语音合成器
            synthesizer = SpeechSynthesizer(model=model, voice=voice_id)
            
            # 调用语音合成服务
            audio_data = synthesizer.call(text)
            
            # 获取请求ID
            request_id = synthesizer.get_last_request_id()
            
            # 构建响应
            response = {
                "status": "success",
                "request_id": request_id
            }
            
            logger.info(f"语音合成成功，声音ID: {voice_id}")
            
            # 返回成功状态、响应数据和音频数据
            return True, response, audio_data
            
        except Exception as e:
            error_msg = f"语音合成失败: {str(e)}"
            logger.error(f"语音合成错误: {str(e)}")
            
            # 返回失败状态和错误信息
            return False, {"error": error_msg}, b''
    

    
    def get_base64_audio(self, api_key: str, voice_id: str, text: str, model: str = None) -> Optional[str]:
        """
        合成语音并返回base64编码
        
        参数:
        api_key: DashScope API密钥
        voice_id: 声音ID
        text: 待合成的文本
        model: 使用的模型，如果不指定则使用默认模型
        
        返回:
        Optional[str]: base64编码的音频数据，失败时返回None
        """
        success, _, audio_data = self.synthesize_speech(api_key, voice_id, text, model)
        
        if success and audio_data:
            try:
                return base64.b64encode(audio_data).decode('utf-8')
            except Exception as e:
                logger.error(f"转换音频为base64失败: {str(e)}")
        
        return None
    
    def create_voice(self, api_key: str, url: str, prefix: str, target_model: str = None) -> Tuple[bool, Dict[str, Any]]:
        """
        创建/复刻声音
        
        参数:
        api_key: DashScope API密钥
        url: 声音样本URL
        prefix: 声音前缀名
        target_model: 目标模型，如果不指定则使用默认模型
        
        返回:
        Tuple[bool, Dict[str, Any]]:
        - 成功状态
        - 响应数据或错误信息
        """
        if target_model is None:
            target_model = self.default_model
            
        try:
            # 设置API密钥
            dashscope.api_key = api_key
            
            # 创建语音注册服务实例
            service = VoiceEnrollmentService()
            
            # 调用create_voice方法复刻声音，并生成voice_id
            voice_id = service.create_voice(target_model=target_model, prefix=prefix, url=url)
            request_id = service.get_last_request_id()
            
            logger.info(f"声音创建成功，声音ID: {voice_id}")
            
            return True, {
                "status": "成功",
                "voice_id": voice_id,
                "request_id": request_id
            }
        except Exception as e:
            error_msg = f"声音创建失败: {str(e)}"
            logger.error(f"声音创建错误: {str(e)}")
            
            return False, {"error": error_msg}